package com.opencee.cloud.uaa.handler;

import com.opencee.common.model.ApiResult;
import com.opencee.common.utils.SpringContextHolder;
import com.opencee.common.utils.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.authentication.BearerTokenExtractor;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 退出成功处理器
 *
 * @author yadu
 */
@Slf4j
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
    private BearerTokenExtractor tokenExtractor = new BearerTokenExtractor();
    private TokenStore tokenStore;

    public CustomLogoutSuccessHandler() {
        this.setUseReferer(true);
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        if (tokenStore == null) {
            // 防止循环依赖,此处使用静态方法获取bean
            tokenStore = SpringContextHolder.getBean(TokenStore.class);
        }
        try {
            // 获取认证信息
            authentication = tokenExtractor.extract(request);
            if (authentication != null && authentication.getPrincipal() != null) {
                String tokenValue = authentication.getPrincipal().toString();
                log.debug("revokeToken tokenValue:{}", tokenValue);
                // 移除token
                OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
                if (accessToken != null) {
                    tokenStore.removeAccessToken(accessToken);
                    OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
                    if (refreshToken != null) {
                        tokenStore.removeRefreshToken(refreshToken);
                    }
                }
            }
        } catch (Exception e) {
            log.error("revokeToken error:{}", e);
        }
        if (WebUtil.acceptHasJson(request)) {
            // 注意:json请求必须携带会话cookie,比如Axios.create({withCredentials=true}). 否则,无法进入登录页
            WebUtil.writeJson(response, ApiResult.ok().msg("退出成功"));
        } else {
            super.onLogoutSuccess(request, response, authentication);
        }
    }

}
